package com.jhsw.roadsun.module.business.util;

import cn.hutool.core.util.StrUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.oned.Code128Writer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import static com.jhsw.roadsun.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.jhsw.roadsun.module.business.enums.ErrorCodeConstants.BUFFERED_IMAGE_IS_NULL;

/**
 * 条形码生成工具类
 *
 * @author Y.sugar
 * @since 2023/3/9 16:03
 */
public class BarCodeUtil {

    /**
     * WIDTH_INCREMENTAL：宽度递增倍数
     * HEIGHT：高度
     * FORMAT：默认文件格式
     */
    private static final int WIDTH_INCREMENTAL = 20;
    private static final int HEIGHT = 100;
    private static final String FORMAT = "png";

    /**
     * 一些默认参数
     */
    private static final Map<EncodeHintType, Object> HINTS = new HashMap<>();

    static {
        // 字符编码
        HINTS.put(EncodeHintType.CHARACTER_SET, "utf-8");
        // 容错等级 L、M、Q、H 其中 L 为最低, H 为最高
        HINTS.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        // 二维码与图片边距
        HINTS.put(EncodeHintType.MARGIN, 2);
    }

    /**
     * 在指定目录下生成图片条形码
     *
     * @param content 待生成的内容
     * @return java.awt.image.BufferedImage：具有图像数据的可访问缓冲图像，实现了 RenderedImage 接口
     */
    public static BufferedImage generateToBufferedImage(String content) {
        if (StrUtil.isNotBlank(content)) {
            Code128Writer code128Writer = new Code128Writer();
            BitMatrix bitMatrix = code128Writer.encode(content, BarcodeFormat.CODE_128, Math.max(WIDTH_INCREMENTAL * content.length(), 250), HEIGHT, HINTS);

            return MatrixToImageWriter.toBufferedImage(bitMatrix);
        }
        return null;
    }

    /**
     * 在指定目录下生成图片条形码
     *
     * @param content 待生成的内容
     * @return java.awt.image.BufferedImage：具有图像数据的可访问缓冲图像，实现了 RenderedImage 接口
     */
    public static byte[] generateToByte(String content) throws IOException {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            BufferedImage bufferedImage = generateToBufferedImage(content);
            if (Objects.isNull(bufferedImage))
                throw exception(BUFFERED_IMAGE_IS_NULL);
            ImageIO.write(bufferedImage, FORMAT, bos);
            return bos.toByteArray();
        }
    }
}
